package com.arpa.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.ntocc.common.common.cache.*;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.ShipmentWarehouseValidate;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.entity.Shipment;
import com.arpa.ntocc.common.service.IShipmentService;
import com.arpa.wms.cache.*;
import com.arpa.wms.common.util.OrderIdGeneratorUtil;
import com.arpa.wms.domain.dto.CollectDTO;
import com.arpa.wms.domain.dto.CollectExcelDTO;
import com.arpa.wms.domain.dto.CollectItemDTO;
import com.arpa.wms.domain.dto.GoodsUnitConversionDTO;
import com.arpa.wms.domain.entity.*;
import com.arpa.wms.domain.enums.CollectStatusEnum;
import com.arpa.wms.domain.enums.DeliveryStatusEnum;
import com.arpa.wms.domain.enums.DeliveryTypeEnum;
import com.arpa.wms.domain.enums.StatusEnum;
import com.arpa.wms.domain.vo.CollectItemVO;
import com.arpa.wms.domain.vo.CollectVO;
import com.arpa.wms.domain.vo.GoodsUnitConversionVO;
import com.arpa.wms.mapper.CollectMapper;
import com.arpa.wms.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static com.arpa.wms.domain.consts.CodeConst.*;
import static com.arpa.wms.domain.consts.CommonConst.*;
import static com.arpa.wms.domain.consts.NumConst.*;
import static com.arpa.wms.domain.consts.TipConst.*;

/**
 * 领用单 服务实现类
 * @author jinss
 * @date 2020-08-20 14:29:30
 **/
@Service
@Log4j2
public class CollectServiceImpl extends ServiceImpl<CollectMapper, Collect> implements ICollectService {

    @Autowired
    private ShipmentCache shipmentCache;
    @Autowired
    private ICollectItemService collectItemService;
    @Autowired
    private IGoodsUnitConversionService goodsUnitConversionService;
    @Autowired
    private IDeliveryService deliveryService;
    @Autowired
    private IDeliveryItemService deliveryItemService;
    @Autowired
    private GoodsUnitConversionCache goodsUnitConversionCache;
    @Autowired
    private PartyCache partyCache;
    @Autowired
    private WarehouseCache warehouseCache;
    @Autowired
    private DictCache dictCache;
    @Autowired
    private WarehouseShipmentCache warehouseShipmentCache;
    @Autowired
    private GoodsCache goodsCache;
    @Autowired
    private IShipmentService shipmentService;
    @Autowired
    private CollectCache collectCache;
    @Autowired
    private UnitCache unitCache;
    @Autowired
    private PartyGroupCache partyGroupCache;

    /**
     * 保存
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public boolean save(Collect entity) {
        if(StrUtil.isBlank(entity.getCode())){
            entity.setCode(OrderIdGeneratorUtil.generatorOrderId(OrderIdGeneratorUtil.OrderTypeEnum.LY, entity.getShipmentCode(), UserUtil.getBranchCode()));
            entity.setGroupCode(UserUtil.getBranchCode());
            entity.setCollectName(entity.getCollectBy());
            entity.setWarehouseName(warehouseCache.translate(entity.getWarehouseCode()));
            entity.setShipmentName(shipmentCache.translate(entity.getShipmentCode()));
        }
        if(StrUtil.isBlank(entity.getCreatedBy())){
            entity.setCreatedBy(UserUtil.getCode());
            entity.setCreatedName(partyCache.translate(UserUtil.getCode()));
        }
        entity.setModifiedBy(UserUtil.getCode());
        entity.setModifiedName(partyCache.translate(UserUtil.getCode()));
        this.saveItem(entity);
        BigDecimal totalQuantity = entity.getCollectItemList().stream().map(CollectItem::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalUnitQuantity = entity.getCollectItemList().stream().map(CollectItem::getUnitQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        entity.setTotalUnitQuantity(totalUnitQuantity);
        entity.setTotalQuantity(totalQuantity);

        return super.save(entity);
    }

    /**
     * 根据code更新实体
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public int updateByCode(Collect entity) {
        entity.setWarehouseName(warehouseCache.translate(entity.getWarehouseCode()));
        entity.setShipmentName(shipmentCache.translate(entity.getShipmentCode()));
        if(StrUtil.isBlank(entity.getModifiedBy())){
            entity.setModifiedBy(UserUtil.getCode());
            entity.setModifiedName(partyCache.translate(UserUtil.getCode()));
        }
        List<String> deleteCodes = entity.getDeleteCodes();
        if (IterUtil.isNotEmpty(deleteCodes)) {
            collectItemService.remove(new QueryWrapper<CollectItem>().lambda().in(CollectItem::getCode, deleteCodes).eq(CollectItem::getGroupCode,UserUtil.getBranchCode()));
        }
        //保存明细
        this.saveItem(entity);
        BigDecimal totalQuantity = entity.getCollectItemList().stream().map(CollectItem::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalUnitQuantity = entity.getCollectItemList().stream().map(CollectItem::getUnitQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        entity.setTotalQuantity(totalQuantity);
        entity.setTotalUnitQuantity(totalUnitQuantity);

        return baseMapper.update(entity,new QueryWrapper<Collect>().lambda().eq(Collect::getCode,entity.getCode()).eq(Collect::getGroupCode,UserUtil.getBranchCode()));
    }

    /**
     * 查询列表
     * @param collectDTO
     * @return
     */
    @Override
    public List<CollectVO> queryList(CollectDTO collectDTO){
        //排序字段名需要驼峰转数据库下划线类型字段名
        if(StrUtil.isNotEmpty(collectDTO.getSortField())){
            collectDTO.setSortField(CommonUtil.camel2Underline(collectDTO.getSortField()));
        }
        List<CollectVO> collectVOList = baseMapper.queryList(collectDTO);
        return collectVOList;
    }

    /**
     * 查询合计,包含总数
     * @param collectDTO
     * @return
     */
    @Override
    public CollectVO queryListSum(CollectDTO collectDTO){
        CollectVO collectVO = baseMapper.queryListSum(collectDTO);
        return collectVO;
    }

    @Override
    public CollectVO getOneByCode(String code) {
        Collect collect = getOne(new QueryWrapper<Collect>().lambda().eq(Collect::getCode, code).eq(Collect::getGroupCode,UserUtil.getBranchCode()));
        if (ObjectUtil.isNull(collect)) {
            log.error("领用单【{}】不存在", code);
            throw new ServiceException("领用单号【 " + code + "】不存在！");
        }

        CollectVO collectVO = new CollectVO();
        BeanUtils.copyProperties(collect, collectVO);
        collectVO.setGroupName(partyGroupCache.translate(collectVO.getGroupCode()));

        CollectItemDTO collectItemDTO = new CollectItemDTO();
        collectItemDTO.setCollectCode(code);
        collectItemDTO.setPageSize(Integer.MAX_VALUE);
        collectItemDTO.setGroupCode(UserUtil.getBranchCode());
        //获取领用单明细信息
        List<CollectItemVO> collectItemList = collectItemService.queryList(collectItemDTO);

        GoodsUnitConversionDTO goodsUnitConversionDTO = new GoodsUnitConversionDTO();
        goodsUnitConversionDTO.setPageSize(Integer.MAX_VALUE);

        collectItemList.stream().forEach(item -> {
            List<GoodsUnitConversionVO> goodsUnitConversionVOList = goodsUnitConversionCache.getVOList(item.getGoodsCode());

            item.setGoodsUnitConversionList(goodsUnitConversionVOList);
        });

        collectVO.setCollectItemList(collectItemList);
        return collectVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean remove(List<String> codes) {
        //遍历删除领用单明细
        codes.forEach(code -> collectItemService.remove(new QueryWrapper<CollectItem>().lambda().eq(CollectItem::getCollectCode, code).eq(CollectItem::getGroupCode,UserUtil.getBranchCode())));
        //删除领用单
        return super.remove(new QueryWrapper<Collect>().lambda().in(Collect::getCode, codes).eq(Collect::getGroupCode,UserUtil.getBranchCode()));
    }

    /**
     * 审核 领用单
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int audit(Collect entity) {
        Collect collect = getOne(new QueryWrapper<Collect>().lambda().eq(Collect::getCode, entity.getCode()).eq(Collect::getGroupCode,UserUtil.getBranchCode()));
        if (ObjectUtil.isNull(collect)) {
            throw new ServiceException(COLLECT_NUMBER + entity.getCode() + NOT_EXIST);
        }

        // 审核通过需要生成 领用类型 的发货单
        if(CollectStatusEnum.PASS.getValue().equals(entity.getStatus())) {
            // 生成发入驻商单
            Delivery delivery = new Delivery();
            BeanUtils.copyProperties(collect, delivery);
            delivery.setCode(OrderIdGeneratorUtil.generatorOrderId(OrderIdGeneratorUtil.OrderTypeEnum.FH, "",UserUtil.getBranchCode()));
            delivery.setSourceCode(entity.getCode());
            delivery.setGroupCode(entity.getGroupCode());
            delivery.setType(DeliveryTypeEnum.OUT_LINGYONG.getValue());
            delivery.setStatus(DeliveryStatusEnum.UN_DISTRIBUTION.getValue());
            delivery.setCreatedBy(UserUtil.getCode());
            delivery.setGmtCreated(LocalDateTime.now());

            // 用于计算明细中的商品种数
            Map<String, Boolean> goodsSortMap = new HashMap<>();
            // 生成发货单明细
            List<CollectItem> collectItemList = collectItemService.list(new QueryWrapper<CollectItem>().lambda().eq(CollectItem::getCollectCode, entity.getCode()).eq(CollectItem::getGroupCode,UserUtil.getBranchCode()));
            List<DeliveryItem> deliveryItemList = Lists.newArrayList();
            collectItemList.stream().forEach(item -> {
                DeliveryItem deliveryItem = new DeliveryItem();
                BeanUtils.copyProperties(item, deliveryItem);
                deliveryItem.setCode(IdUtil.simpleUUID());
                deliveryItem.setDeliveryCode(delivery.getCode());
                deliveryItem.setQuantity(item.getUnitQuantity());
                deliveryItem.setTotalNum(item.getQuantity());
                deliveryItem.setCreatedBy(UserUtil.getCode());
                deliveryItem.setGmtCreated(LocalDateTime.now());
                deliveryItem.setSourceItemCode(item.getCode());
                deliveryItem.setTotalNum(item.getQuantity());
                goodsSortMap.put(item.getGoodsCode(), true);

                deliveryItemList.add(deliveryItem);
            });

            BigDecimal totalQuantity = deliveryItemList.stream().map(DeliveryItem::getTotalNum).reduce(BigDecimal.ZERO, BigDecimal::add);
            delivery.setTotalNum(totalQuantity);
            // 商品种类
            delivery.setGoodsSortQuantity(new BigDecimal(Integer.toString(goodsSortMap.size())));
            // 保存发货单
            deliveryService.save(delivery);
            //保存发货单明细
            deliveryItemService.saveBatch(deliveryItemList);
        }

        // 更新 领用单
        entity.setGmtApproved(LocalDateTime.now());
        entity.setApprovedBy(UserUtil.getCode());
        entity.setApprovedName(partyCache.translate(UserUtil.getCode()));
        entity.setModifiedBy(UserUtil.getCode());
        entity.setModifiedName(partyCache.translate(UserUtil.getCode()));
        return baseMapper.update(entity, new QueryWrapper<Collect>().lambda().eq(Collect::getCode, entity.getCode()).eq(Collect::getGroupCode,UserUtil.getBranchCode()));
    }

    /**
     * 更新 领用单 状态
     * @param code
     * @param status
     * @return
     */
    @Override
    public int updateStatusByCode(String code, String status) {
        Collect collect = new Collect();
        collect.setCode(code);
        collect.setStatus(status);
        collect.setModifiedBy(UserUtil.getCode());
        collect.setModifiedName(partyCache.translate(UserUtil.getCode()));

        return baseMapper.update(collect, new QueryWrapper<Collect>().lambda().eq(Collect::getCode, collect.getCode()).eq(Collect::getGroupCode,UserUtil.getBranchCode()));
    }

    @Override
    public List<CollectExcelDTO> collectView(List<CollectExcelDTO> collectExcelDTOList) {
        //校验授权仓库code和入驻商code不能为空
        ShipmentWarehouseValidate.validateShipmentCodesAndWarehouseCodes();
        String branchCode = UserUtil.getBranchCode();
        // 校验Excel里必填项是否有空值
        validateNotBlank(collectExcelDTOList);
        // 校验仓库是否相同 只允许单仓导入
        validateSameWarehouse(collectExcelDTOList);
        // 校验仓库是否启用并且开启库位管理
        validateWarehouseLocationManagement(collectExcelDTOList, branchCode);
        // 校验入驻商是否相同 只允许单入驻商导入
        validateSameShipment(collectExcelDTOList);
        List<String> authorizeShipmentCodes = UserUtil.getAuthorizeShipmentCodes();
        List<Shipment> shipments = UserUtil.getAuthorizeShipmentList().stream().map(r->BeanUtil.toBean(r,Shipment.class)).collect(Collectors.toList());
        // 校验 当前用户授权的仓库、入驻商
        validateAuthorizationWarehouseShipment(collectExcelDTOList.get(NUM_ZERO).getWarehouseSerialNumber(), collectExcelDTOList.get(NUM_ZERO).getShipmentSerialNumber(), authorizeShipmentCodes, branchCode);
        // 校验Excel里是否有重复数据
        validateRepeatData(collectExcelDTOList);

        List<Map<String, Object>> warehouseCacheAll = warehouseCache.getAllByGroupCode(UserUtil.getBranchCode());
        List<Map<String, Object>> goodsCacheAll = goodsCache.getAllByGroupCode(UserUtil.getBranchCode());
        List<DictCacheDO> dictCacheAll = dictCache.getListByType(COLLECT_TYPE, UserUtil.getBranchCode());

        IntStream.range(NUM_ZERO, collectExcelDTOList.size()).forEach(index -> {
            // 验证一些字符长度
            String collectDept = collectExcelDTOList.get(index).getCollectDept();
            if (StrUtil.isNotBlank(collectDept) && StrUtil.length(collectDept) > TWO_HUNDRED_FIFTY_FIVE.intValue()) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + COLLECT_DEPT_NAME + TOO_LONG);
            }
            String remarks = collectExcelDTOList.get(index).getRemarks();
            if (StrUtil.isNotBlank(remarks) && StrUtil.length(remarks) > TWO_HUNDRED_FIFTY_FIVE.intValue()) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + REMARKS_NAME + TOO_LONG);
            }
            // 校验Excel里的值，在系统中是否存在
            List<Map<String, Object>> warehouseCaches = warehouseCacheAll.stream().filter(item -> collectExcelDTOList.get(index).getWarehouseSerialNumber().equals(item.get(SERIAL_NUMBER)) &&
                    branchCode.equals(item.get(GROUP_CODE))).collect(Collectors.toList());
            if(CollUtil.isEmpty(warehouseCaches)) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + WAREHOUSE + NOT_EXIST);
            }
            collectExcelDTOList.get(index).setWarehouseCode((String) warehouseCaches.get(NUM_ZERO).get(CODE));
            collectExcelDTOList.get(index).setWarehouseName((String) warehouseCaches.get(NUM_ZERO).get(NAME));

            List<Shipment> shipments1 = shipments.stream().filter(item -> collectExcelDTOList.get(index).getShipmentSerialNumber().equals(item.getPartyCode())).collect(Collectors.toList());
            if (CollUtil.isEmpty(shipments1)) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + SHIPMENT + NOT_EXIST);
            }
            if (!NUM_THREE.equals(shipments1.get(NUM_ZERO).getAuthStatus())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + SHIPMENT + UNAPPROVE_NAME);
            }
//            saas改造入驻商和承运商没有绑定关系
//            List<Map<String, Object>> warehouseShipmentCacheAll = warehouseShipmentCache.get((String) warehouseCaches.get(NUM_ZERO).get(CODE));
//            List<Map<String, Object>> warehouseShipments = warehouseShipmentCacheAll.stream().filter(item -> item.get(SHIPMENT_CODE).equals(shipments1.get(NUM_ZERO).getPartyCode())).collect(Collectors.toList());
//            if(CollUtil.isEmpty(warehouseShipments)) {
//                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + SHIPMENT_NOT_BELONG_TO_WAREHOUSE);
//            }
//            collectExcelDTOList.get(index).setShipmentCode((String) warehouseShipments.get(NUM_ZERO).get(SHIPMENT_CODE));
            collectExcelDTOList.get(index).setShipmentCode(shipments1.get(NUM_ZERO).getPartyCode());
            collectExcelDTOList.get(index).setShipmentName(shipments1.get(NUM_ZERO).getUserName());

            List<DictCacheDO> dictCacheDOList = dictCacheAll.stream().filter(item -> item.getName().equals(collectExcelDTOList.get(index).getTypeName())).collect(Collectors.toList());
            if(CollUtil.isEmpty(dictCacheDOList)) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + COLLECT_TYPE_NAME + NOT_EXIST);
            }
            collectExcelDTOList.get(index).setType(dictCacheDOList.get(NUM_ZERO).getCode());
            collectExcelDTOList.get(index).setTypeName(dictCacheDOList.get(NUM_ZERO).getName());

            List<Map<String, Object>> goodsCaches = goodsCacheAll.stream().filter(item -> collectExcelDTOList.get(index).getGoodCode().equals(item.get(GOOD_CODE)) &&
                    shipments1.get(NUM_ZERO).getPartyCode().equals(item.get(SHIPMENT_CODE))).collect(Collectors.toList());
            if(CollUtil.isEmpty(goodsCaches)) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS + NOT_EXIST);
            }
            if (!StatusEnum.ACTIVE.getValue().equals(goodsCaches.get(NUM_ZERO).get(STATUS))) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS + NOT_ENABLED);
            }
            collectExcelDTOList.get(index).setGoodsCode((String) goodsCaches.get(NUM_ZERO).get(CODE));
            collectExcelDTOList.get(index).setGoodsName((String) goodsCaches.get(NUM_ZERO).get(NAME));
            collectExcelDTOList.get(index).setGoodsBarCode((String) goodsCaches.get(NUM_ZERO).get(BAR_CODE));

            List<GoodsUnitConversion> goodsUnitConversions = goodsUnitConversionCache.get((String) goodsCaches.get(NUM_ZERO).get(CODE));
            List<GoodsUnitConversion> goodsUnitConversionList = goodsUnitConversions.stream().filter(item -> item.getUnitName()
                    .equals(collectExcelDTOList.get(index).getGoodsUnitName())).collect(Collectors.toList());
            if(CollUtil.isEmpty(goodsUnitConversionList)) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_UNIT + NOT_EXIST);
            }
            Map<String, Object> unitCacheMap = unitCache.get(goodsUnitConversionList.get(NUM_ZERO).getUnitCode());
            if (!StatusEnum.ACTIVE.getValue().equals(unitCacheMap.get(STATUS))) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_UNIT + NOT_ENABLED);
            }
            collectExcelDTOList.get(index).setGoodsUnit(goodsUnitConversionList.get(NUM_ZERO).getUnitCode());
            collectExcelDTOList.get(index).setGoodsUnitName(goodsUnitConversionList.get(NUM_ZERO).getUnitName());

            List<GoodsUnitConversion> basicUnitList = goodsUnitConversions.stream().filter(item -> item.getFlag().equals(NUM_ONE)).collect(Collectors.toList());
            collectExcelDTOList.get(index).setBasicUnit(basicUnitList.get(NUM_ZERO).getUnitCode());
            collectExcelDTOList.get(index).setBasicUnitName(basicUnitList.get(NUM_ZERO).getUnitName());
            collectExcelDTOList.get(index).setBasicQuantity(basicUnitList.get(NUM_ZERO).getQuantity());
            collectExcelDTOList.get(index).setUnitQuantity(new BigDecimal(collectExcelDTOList.get(index).getCollectQuantity()));
        });

        collectCache.initCache(collectExcelDTOList);
        return collectExcelDTOList;
    }

    @Override
    @Transactional(rollbackFor={Exception.class})
    public void collectImport() {
        List<CollectExcelDTO> collectExcelDTOList = collectCache.getCache();
        if(CollUtil.isNotEmpty(collectExcelDTOList)) {
            Collect collect = new Collect();
            collect.setCode(OrderIdGeneratorUtil.generatorOrderId(OrderIdGeneratorUtil.OrderTypeEnum.LY, "",UserUtil.getBranchCode()));
            collect.setWarehouseCode(collectExcelDTOList.get(NUM_ZERO).getWarehouseCode());
            collect.setWarehouseName(collectExcelDTOList.get(NUM_ZERO).getWarehouseName());
            collect.setShipmentCode(collectExcelDTOList.get(NUM_ZERO).getShipmentCode());
            collect.setShipmentName(collectExcelDTOList.get(NUM_ZERO).getShipmentName());
            collect.setGroupCode(UserUtil.getBranchCode());
            collect.setCollectDept(collectExcelDTOList.get(NUM_ZERO).getCollectDept());
            collect.setType(collectExcelDTOList.get(NUM_ZERO).getType());
            collect.setStatus(CollectStatusEnum.NEW.getValue());
            collect.setCreatedBy(UserUtil.getCode());
            collect.setCreatedName(partyCache.translate(UserUtil.getCode()));

            List<CollectItem> collectItemList = collectExcelDTOList.stream().map(item -> {
                CollectItem collectItem = new CollectItem();
                BeanUtils.copyProperties(item, collectItem);

                return collectItem;
            }).collect(Collectors.toList());

            collect.setCollectItemList(collectItemList);
            save(collect);
            collectCache.removeCache();
        }
    }

    /**
     * 保存 领用单明细
     * @param entity
     */
    private void saveItem(Collect entity) {
        entity.getCollectItemList().forEach(r -> {
            if (StrUtil.isNotBlank(r.getCode())) {
                r.setGroupCode(UserUtil.getBranchCode());
                r.setQuantity(r.getUnitQuantity().multiply(r.getBasicQuantity()));
                r.setModifiedBy(UserUtil.getCode());
                r.setModifiedName(partyCache.translate(UserUtil.getCode()));
            } else {
                r.setCode(IdUtil.simpleUUID());
                r.setGroupCode(UserUtil.getBranchCode());
                r.setCollectCode(entity.getCode());
                r.setQuantity(r.getUnitQuantity().multiply(r.getBasicQuantity()));
                Map<String, Object> goodsMap = goodsCache.get(r.getGoodsCode());
                r.setSpec((String) goodsMap.get("spec"));
                r.setCreatedBy(entity.getCreatedBy());
                r.setCreatedName(partyCache.translate(UserUtil.getCode()));
            }

        });
        // 批量保存或删除明细
        collectItemService.saveOrUpdateBatch(entity.getCollectItemList());
    }

    /**
     * 校验Excel里必填项是否有空值
     * @param collectExcelDTOList
     */
    private void validateNotBlank(List<CollectExcelDTO> collectExcelDTOList) {
        for(int index = NUM_ZERO; index < collectExcelDTOList.size(); index++){
            // 校验Excel里必填项是否有空值
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getWarehouseSerialNumber())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + WAREHOUSE_SERIAL_NUMBER + NOT_BLANK);
            }
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getWarehouseName())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + WAREHOUSE_NAME + NOT_BLANK);
            }
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getShipmentSerialNumber())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + SHIPMENT_SERIAL_NUMBER + NOT_BLANK);
            }
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getShipmentName())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + SHIPMENT_NAME + NOT_BLANK);
            }
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getTypeName())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + COLLECT_TYPE_NAME + NOT_BLANK);
            }
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getGoodCode())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOOD_CODE_NAME + NOT_BLANK);
            }
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getGoodsName())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_NAME_TEXT + NOT_BLANK);
            }
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getGoodsUnitName())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + GOODS_UNIT + NOT_BLANK);
            }
            if (StrUtil.isBlank(collectExcelDTOList.get(index).getCollectQuantity())) {
                throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + QUANTITY + NOT_BLANK);
            }
        }

    }

    /**
     * 校验是否有重复数据
     * @param collectExcelDTOList
     */
    private void validateRepeatData(List<CollectExcelDTO> collectExcelDTOList) {
        List<CollectExcelDTO> collectExcelList = collectExcelDTOList;
        Stream.iterate(NUM_ZERO, index -> index + NUM_ONE).limit(collectExcelDTOList.size()).forEach(index -> {
            Stream.iterate(NUM_ZERO, indexJ -> indexJ + NUM_ONE).limit(collectExcelList.size()).forEach(indexJ -> {
                boolean warehouseFlag = collectExcelDTOList.get(index).getWarehouseSerialNumber().equals(collectExcelList.get(indexJ).getWarehouseSerialNumber());
                boolean shipmentFlag = collectExcelDTOList.get(index).getShipmentSerialNumber().equals(collectExcelList.get(indexJ).getShipmentSerialNumber());
                boolean goodsFlag = collectExcelDTOList.get(index).getGoodCode().equals(collectExcelList.get(indexJ).getGoodCode());
                boolean typeFlag = collectExcelDTOList.get(index).getTypeName().equals(collectExcelList.get(indexJ).getTypeName());

                if(warehouseFlag && shipmentFlag && goodsFlag && typeFlag && !index.equals(indexJ)) {
                    throw new ServiceException(TIP_PREFIX + (index + NUM_THREE) + LINE + AND_NAME + TIP_PREFIX + (indexJ + NUM_THREE) + LINE + REPEAT_DATA);
                }
            });
        });
    }

    /**
     * 校验仓库是否相同  只允许单仓导入
     * @param collectExcelDTOList
     */
    private void validateSameWarehouse(List<CollectExcelDTO> collectExcelDTOList) {
        collectExcelDTOList.forEach(item -> {
            collectExcelDTOList.forEach(item1 -> {
                if(!item.getWarehouseSerialNumber().equals(item1.getWarehouseSerialNumber())) {
                    throw new ServiceException(EXIST + WAREHOUSE_SERIAL_NUMBER + NOT_SAME + DATA_NAME);
                }
            });
        });
    }

    /**
     * 校验入驻商是否相同 只允许单入驻商导入
     * @param collectExcelDTOList
     */
    private void validateSameShipment(List<CollectExcelDTO> collectExcelDTOList) {
        collectExcelDTOList.forEach(item -> {
            collectExcelDTOList.forEach(item1 -> {
                if(!item.getShipmentSerialNumber().equals(item1.getShipmentSerialNumber())) {
                    throw new ServiceException(EXIST + SHIPMENT_SERIAL_NUMBER + NOT_SAME + DATA_NAME);
                }
            });
        });
    }

    /**
     * 校验仓库是否启用并且开启库位管理
     * @param collectExcelDTOList
     * @param branchCode
     */
    private void validateWarehouseLocationManagement(List<CollectExcelDTO> collectExcelDTOList, String branchCode) {
        List<Map<String, Object>> warehouseCacheAll = warehouseCache.getAllByGroupCode(branchCode);
        List<Map<String, Object>> warehouseMaps = warehouseCacheAll.stream().filter(item -> item.get(SERIAL_NUMBER).equals(collectExcelDTOList.get(NUM_ZERO).getWarehouseSerialNumber()) && branchCode.equals(item.get(GROUP_CODE))).collect(Collectors.toList());
        if(CollUtil.isEmpty(warehouseMaps)) {
            throw new ServiceException(WAREHOUSE + NOT_EXIST);
        }
        String status = (String) warehouseMaps.get(NUM_ZERO).get(STATUS);
        if(!StatusEnum.ACTIVE.getValue().equals(status)) {
            throw new ServiceException(WAREHOUSE + NOT_ENABLED);
        }
        Integer locationManagement = (Integer) warehouseMaps.get(NUM_ZERO).get(LOCATION_MANAGEMENT);
        if(!NUM_ONE.equals(locationManagement)) {
            throw new ServiceException(WAREHOUSE + NOT_LOCATION_MANAGEMENT);
        }
    }

    /**
     * 校验 当前用户授权的仓库、入驻商
     * @param warehouseSerialNumber
     * @param shipmentSerialNumber
     * @param branchCode
     */
    private void validateAuthorizationWarehouseShipment(String warehouseSerialNumber, String shipmentSerialNumber, List<String> shipmentsCodes, String branchCode) {
        List<Map<String,Object>> warehouseList = UserUtil.getAuthorizeWarehouseList();
        if(IterUtil.isEmpty(warehouseList)){
            throw new ServiceException(CURRENT_USER_NAME + WITHOUT + WAREHOUSE + PERMISSIONS);
        }


         boolean bool = warehouseList.stream().map(r->
            BeanUtil.toBean(r,Warehouse.class)
        ).map(Warehouse::getGroupCode).filter(s->StrUtil.equals(branchCode,s)).count()>0;

        boolean bool2 = warehouseList.stream().map(r->
                BeanUtil.toBean(r,Warehouse.class)
        ).map(Warehouse::getSerialNumber).filter(s->StrUtil.equals(warehouseSerialNumber,s)).count()>0;

        if (!bool || !bool2) {
            throw new ServiceException(CURRENT_USER_NAME + WITHOUT + WAREHOUSE + LEFT_BRACKET + warehouseSerialNumber + RIGHT_BRACKET + PERMISSIONS);
        }
        if (!shipmentsCodes.contains(shipmentSerialNumber)) {
            throw new ServiceException(CURRENT_USER_NAME + WITHOUT + SHIPMENT + LEFT_BRACKET + shipmentSerialNumber + RIGHT_BRACKET + PERMISSIONS);
        }
    }

}
